package com.bitcointoolkit.web.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.bitcointoolkit.web.security.CSRFTokenManager;
import com.bitcointoolkit.web.utils.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 安全性拦截器，拦截常见攻击如：CSRF漏洞
 * 
 * @author caisirius
 */
public class SecurityInterceptor extends BaseInterceptor {
	
	private Logger logger = LoggerFactory.getLogger(SecurityInterceptor.class);

	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		//针对POST拦截，规范提交数据到后台必须用POST方法
		if(HttpUtils.isPost(request)){
			if(isValidCsrfHeaderToken(request)){
				return true;
			}else{
				response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid request header,could not find a valid CSRF_TOKEN!");
				return false;
			}
		}
		return true;
	}

	/**
	 * 配合前端AJAX SETUP使用，在发送AJAX请求时寻找Hidden表单token值存入header
	 * eg:
	 *      var headers = {};
		    headers['RequestVerificationToken'] = $("#CSRFToken").val();
		    $.ajax({
		        type: "POST",
		        headers: headers,
		        url: base + "ajax/domain/delete.do",
		        data: "id=123",
		        dataType:"json",
		        success: function(data)
		        {
		        }
		    });
	 * @param request
	 * @return
	 */
	private boolean isValidCsrfHeaderToken(HttpServletRequest request) {
		if (request.getHeader("RequestVerificationToken") == null
				|| request.getSession().getAttribute(
						CSRFTokenManager.CSRF_TOKEN_FOR_SESSION_ATTR_NAME) == null
				|| !request
						.getHeader("RequestVerificationToken")
						.equals(request
								.getSession()
								.getAttribute(
										CSRFTokenManager.CSRF_TOKEN_FOR_SESSION_ATTR_NAME)
								.toString())) {
			logger.warn("Invalid request header,could not find a valid CSRF_TOKEN!");
//			return false;
		}
		return true;
	}
}
